package com.xyg.common.interceptor;

import static com.xyg.common.Constants.MESSAGE_ATTRIBUTE;
import static com.xyg.common.Constants.TOKEN_ATTRIBUTE;

import java.lang.reflect.Method;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.xyg.support.Message;

import lombok.extern.slf4j.Slf4j;

/**
 * 表单重复提交拦截
 * 
 * @author lzn
 *
 */
@Slf4j
public class DuplicateCheckerInterceptor extends HandlerInterceptorAdapter {

	private final ThreadLocal<Boolean> duplicateChecker = new ThreadLocal<>();

	/** 重复提交后的跳转地址 */
	private String afterDuplicateForwardUrl = "";

	private String tip = "repeat.submit";

	public void setTip(String tip) {
		this.tip = tip;
	}

	/***
	 * 支持spring注入
	 * 
	 * @param afterDuplicateForwardUrl
	 *            重复提交后的跳转地址
	 */
	public void setAfterDuplicateForwardUrl(String afterDuplicateForwardUrl) {
		this.afterDuplicateForwardUrl = afterDuplicateForwardUrl;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();

		Token annotation = method.getAnnotation(Token.class);
		if (annotation != null) {
			boolean save = annotation.save();
			if (save) {
				request.getSession(false).setAttribute(TOKEN_ATTRIBUTE, UUID.randomUUID().toString());
			}
			boolean remove = annotation.remove();
			if (remove) {
				boolean isRepeat = isRepeatSubmit(request);
				duplicateChecker.set(isRepeat);
				if (isRepeat) {
					log.warn("please don't repeat submit,[url:" + request.getServletPath() + "]");
					//return false;
				}
				request.getSession(false).removeAttribute(TOKEN_ATTRIBUTE);
			}
		}
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		if (duplicateChecker.get() != null && duplicateChecker.get()) {
			request.getSession().setAttribute(MESSAGE_ATTRIBUTE, Message.danger(tip));
			request.getRequestDispatcher(afterDuplicateForwardUrl).forward(request, response);
			duplicateChecker.set(false);
		}
		super.postHandle(request, response, handler, modelAndView);
	}

	private boolean isRepeatSubmit(HttpServletRequest request) {
		String serverToken = (String) request.getSession(false).getAttribute(TOKEN_ATTRIBUTE);
		if (serverToken == null) {
			return true;
		}
		String clientToken = request.getParameter(TOKEN_ATTRIBUTE);
		if (clientToken == null) {
			return true;
		}
		if (!serverToken.equals(clientToken)) {
			return true;
		}
		return false;
	}
}
